#include <cmath>
#include "MathUtils.h"

class ViewMatrix {

public:
	float matrix[4][4];

	ViewMatrix() {
		matrix[0][0] = 1.0f; matrix[0][1] = 0.0f; matrix[0][2] = 0.0f; matrix[0][3] = 0.0f;
		matrix[1][0] = 0.0f; matrix[1][1] = 1.0f; matrix[1][2] = 0.0f; matrix[1][3] = 0.0f;
		matrix[2][0] = 0.0f; matrix[2][1] = 0.0f; matrix[2][2] = 1.0f; matrix[2][3] = 0.0f;
		matrix[3][0] = 0.0f; matrix[3][1] = 0.0f; matrix[3][2] = 0.0f; matrix[3][3] = 1.0f;
	}

	void lookAt(float eyeX, float eyeY, float eyeZ, float dstX, float dstY, float dstZ, float upX, float upY, float upZ) {
		float dirX = eyeX - dstX;
		float dirY = eyeY - dstY;
		float dirZ = eyeZ - dstZ;
		normalize(dirX, dirY, dirZ);
		float sideX = upY * dirZ - upZ * dirY;
		float sideY = upZ * dirX - upX * dirZ;
		float sideZ = upX * dirY - upY * dirX;
		normalize(sideX, dirY, sideZ);
		upX = dirY * sideZ - dirZ * sideY;
		upY = dirZ * sideX - dirX * sideZ;
		upZ = dirX * sideY - dirY * sideX;
		normalize(upX, upY, upZ);

		matrix[0][0] = sideX;
		matrix[0][1] = sideY;
		matrix[0][2] = sideZ;
		matrix[0][3] = - eyeX * sideX - eyeY * sideY - eyeZ * sideZ;

		matrix[1][0] = upX;
		matrix[1][1] = upY;
		matrix[1][2] = upZ;
		matrix[1][3] = - eyeX * upX - eyeY * upY - eyeZ * upZ;

		matrix[2][0] = dirX;
		matrix[2][1] = dirY;
		matrix[2][2] = dirZ;
		matrix[2][3] = - eyeX * dirX - eyeY * dirY - eyeZ * dirZ;
	}

	void lookTo(float eyeX, float eyeY, float eyeZ, float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
		
		normalize(dirX, dirY, dirZ);
		dirX = -dirX;
		dirY = -dirY;
		dirZ = -dirZ;
		float sideX = upY * dirZ - upZ * dirY;
		float sideY = upZ * dirX - upX * dirZ;
		float sideZ = upX * dirY - upY * dirX;
		normalize(sideX, dirY, sideZ);
		upX = dirY * sideZ - dirZ * sideY;
		upY = dirZ * sideX - dirX * sideZ;
		upZ = dirX * sideY - dirY * sideX;
		normalize(upX, upY, upZ);

		matrix[0][0] = sideX;
		matrix[0][1] = sideY;
		matrix[0][2] = sideZ;
		matrix[0][3] = - eyeX * sideX - eyeY * sideY - eyeZ * sideZ;

		matrix[1][0] = upX;
		matrix[1][1] = upY;
		matrix[1][2] = upZ;
		matrix[1][3] = - eyeX * upX - eyeY * upY - eyeZ * upZ;

		matrix[2][0] = dirX;
		matrix[2][1] = dirY;
		matrix[2][2] = dirZ;
		matrix[2][3] = - eyeX * dirX - eyeY * dirY - eyeZ * dirZ;
	}
};